package com.learnyou.server.xingzuo.dao.repository.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.useragent.UserAgent;
import com.learnyou.server.xingzuo.common.exception.LearnyouBootException;
import com.learnyou.server.xingzuo.common.constants.ErrorCode;
import com.learnyou.server.xingzuo.common.enums.ApiConfigEnum;
import com.learnyou.server.xingzuo.common.util.ServletUtils;
import com.learnyou.server.xingzuo.common.util.ip.AddressUtils;
import com.learnyou.server.xingzuo.common.util.ip.IpUtils;
import com.learnyou.server.xingzuo.dao.repository.entity.SysOperLog;
import com.learnyou.server.xingzuo.dao.repository.mapper.SysOperLogMapper;
import com.learnyou.server.xingzuo.dao.repository.service.ISysOperLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.learnyou.server.xingzuo.dto.resultDTO.SysOperLogStatDTO;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Objects;
import java.util.stream.Stream;

/**
 * <p>
 * 操作日志记录 服务实现类
 * </p>
 *
 * @author heweifeng
 * @since 2022-11-21
 */
@Service
public class SysOperLogServiceImpl extends ServiceImpl<SysOperLogMapper, SysOperLog> implements ISysOperLogService {

    @Override
    public void log(int code, String title) {
        HttpServletRequest request = ServletUtils.getRequest();
        String requestURI = ServletUtils.getRequestUri(request);
        UserAgent ua = ServletUtils.getUserAgent();
        String browser = ua.getBrowser().toString();//Chrome
        String version = ua.getVersion();//14.0.835.163
        String os = ua.getOs().toString();//Windows 7
        String ipAddr = IpUtils.getIpAddr(request);
        String address = AddressUtils.getRealAddressByIP(ipAddr);
        save(
                new SysOperLog().setOperCode(code)
                        .setTitle(title)
                        .setOperTime(new Date())
                        .setRequestUri(requestURI)
                        .setAddress(address)
                        .setOs(os)
                        .setBrowserVersion(version)
                        .setBrowser(browser)
                        .setIpAddr(ipAddr)
        );
    }

    @Override
    public void checkReqFrequency(int code, int timeLimit, DateUnit timeUnit, int maxReqCount) {
        HttpServletRequest request = ServletUtils.getRequest();
        String ipAddr = IpUtils.getIpAddr(request);
        Date end = new Date();
        Date start = new Date();
        if (Objects.equals(timeUnit, DateUnit.MINUTE)) {
            end =  DateUtil.offsetMinute(start, timeLimit);
        }
        if (Objects.equals(timeUnit, DateUnit.HOUR)){
            end = DateUtil.offsetHour(start, timeLimit);
        }
        Integer count = lambdaQuery()
                .between(SysOperLog::getOperTime, start, end)
                .eq(SysOperLog::getIpAddr, ipAddr)
                .eq(SysOperLog::getOperCode, code)
                .count();
        if (count > maxReqCount){
            throw new LearnyouBootException(ErrorCode.TO_MANY_REQUEST);
        }
    }
}
